package com.cyys.modules.system.controller.param;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cyys.common.annotation.SystemLog;
import com.cyys.common.ql.AR;
import com.cyys.common.ql.JSONData;
import com.cyys.common.utils.StringUtil;
import com.cyys.common.utils.file.FileUtil;
import com.cyys.modules.core.controller.BaseAction;
import com.cyys.modules.core.sysParam.ParamRegionUtil;
import com.cyys.modules.core.sysParam.SystemConfigureUtil;
import com.cyys.modules.core.sysParam.SystemConstants;
import com.cyys.modules.core.utils.exportExcel.CommonExportUtil;
import com.cyys.modules.system.model.param.ParamRegion;
import com.cyys.modules.system.service.param.ParamRegionService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@Controller
@RequestMapping("/sys/paramRegion")
public class ParamRegionAction extends BaseAction {

	@Resource
	private ParamRegionService paramRegionService;

	@GetMapping("/add/input")
	@RequiresPermissions("sys:paramRegion:add")
	public String input(ParamRegion paramRegion, Model model)  {
		paramRegion.setParentName(paramRegionService.getRegionNameById(paramRegion.getParentId()));
		model.addAttribute("paramRegion", paramRegion);
		return "module/system/param/paramRegion-input";
	}

	@ResponseBody
	@PostMapping("/add/save")
	@RequiresPermissions(value = "sys:paramRegion:add")
	@SystemLog(module = "系统参数", methods = "地域参数-保存地域参数")
	public AR save(ParamRegion paramRegion) throws Exception {
		return paramRegionService.save(paramRegion);
	}

	@GetMapping("/edit/input")
	@RequiresPermissions(value = "sys:paramRegion:edit")
	public String editInput(ParamRegion paramRegion, Model model)  {
		paramRegion= paramRegionService.getById(paramRegion.getId());
		paramRegion.setParentName(paramRegionService.getRegionNameById(paramRegion.getParentId()));
		model.addAttribute("paramRegion", paramRegion);
		return "module/system/param/paramRegion-input";
	}

	@ResponseBody
	@PostMapping("/edit/save")
	@RequiresPermissions(value ={ "sys:paramRegion:edit","sys:paramRegion:add"},logical=Logical.OR)
	@SystemLog(module = "系统参数", methods = "地域参数-更新地域参数")
	public AR edit(ParamRegion paramRegion) throws Exception {
		return paramRegionService.save(paramRegion);
	}


	@GetMapping("/list")
	@RequiresPermissions("sys:paramRegion:list")
	public String list() {
		return "module/system/param/paramRegion-list";
	}

	@ResponseBody
	@PostMapping("/del/deleteById")
	@RequiresPermissions("sys:paramRegion:del")
	@SystemLog(module = "系统参数", methods = "地域参数-删除地域参数")
	public AR deleteById(String id)  throws Exception {
		return paramRegionService.deleteById(id);
	}

	@ResponseBody
	@PostMapping("/list/paramRegionList")
	@RequiresPermissions("sys:paramRegion:list")
	public String paramRegionlist(ParamRegion paramRegion, Page page)  {
		QueryWrapper qw= new QueryWrapper(paramRegion);
		qw.orderByAsc("level,sort");
		if(StringUtil.isBlank(paramRegion.getParentId()) && "true".equals(SystemConfigureUtil.get(SystemConstants.ONLY_DEFAULT_PROVINCE))){
			ParamRegion t_paramRegion= paramRegionService.getByCityCode(SystemConfigureUtil.get(SystemConstants.SYSTEM_PROVINCE_CODE));
			if(paramRegion!=null){
				paramRegion.setParentId(t_paramRegion.getId());
			}else{
				return JSONData.toLayerData(page);//无数据
			}
		}
		return JSONData.toLayerData(paramRegionService.list(page, qw,false));
	}

	@ResponseBody
	@PostMapping("/list/listForTree")
	@RequiresPermissions("sys:paramRegion:list")
	public List<ParamRegion> listForTree(String parentId) throws Exception {
		if(StringUtil.isBlank(parentId) && "true".equals(SystemConfigureUtil.get(SystemConstants.ONLY_DEFAULT_PROVINCE))){
			ParamRegion paramRegion= paramRegionService.getByCityCode(SystemConfigureUtil.get(SystemConstants.SYSTEM_PROVINCE_CODE));
			if(paramRegion!=null){
				return paramRegionService.listForTree(paramRegion.getId(), true);
			}
			return new ArrayList<>();//无数据
		}
		return paramRegionService.listForTree(parentId, false);
	}

	@ResponseBody
	@PostMapping("/init/initParamRegion")
	@RequiresPermissions("sys:paramRegion:init")
	@SystemLog(module = "系统参数", methods = "地域参数-更新地域参数缓存")
	public AR initParamRegion() throws Exception {
		ParamRegionUtil.initParamRegion(paramRegionService);
		return AR.ok("更新缓存成功");
	}

	@ResponseBody
	@PostMapping("/del/deleteBatch")
	@RequiresPermissions("sys:paramRegion:del")
	@SystemLog(module = "系统参数", methods = "地域参数-批量删除")
	public AR deleteBatch(String ids) throws Exception{
		return paramRegionService.deleteBatchIds(ids);
	}

	@ResponseBody
	@PostMapping("/init/createInitFile")
	@RequiresPermissions("sys:paramRegion:init")
	@SystemLog(module = "系统参数", methods = "地域参数-更新地域文件")
	public AR createInitFile() throws Exception{
		List<ParamRegion> paramRegionList = paramRegionService.listAllTree(false);
		String fileString = createRegionMain(paramRegionList);

		// 真实路径webapp/js/city.json
		String basePath = session.getServletContext().getRealPath("/static/js/distpicke") + File.separator;
		FileUtil.createFile(basePath, "distpicker.data.js", fileString);

		// 更新redis数据文件版本号
		Integer fileDataVersion =  new Random().nextInt(1000000);
		System.out.println("=======数据文件版本号："+fileDataVersion);
		session.getServletContext().setAttribute("fileDataVersion", fileDataVersion.toString());
		return AR.ok("更新成功");
	}

	private String createRegionMain(List<ParamRegion> list)  {
		StringBuffer fileString = new StringBuffer();
		fileString.append("(function (factory) {");
		fileString.append("if (typeof define === 'function' && define.amd) {");
		fileString.append("define('ChineseDistricts', [], factory);");
		fileString.append("} else {");
		fileString.append("factory();");
		fileString.append("}");
		fileString.append("})(function () {");
		fileString.append("var ChineseDistricts = {");
		//组装地域数据
		ParamRegion topRegion= new ParamRegion();
		topRegion.setCityCode("86");//前端默认顶级节点
		topRegion.setChildren(list);
		createRegionString(fileString, topRegion);

		fileString.append("};");
		fileString.append("if (typeof window !== 'undefined') {");
		fileString.append("window.ChineseDistricts = ChineseDistricts;");
		fileString.append("}");
		fileString.append("return ChineseDistricts;");
		fileString.append("});");
		return fileString.toString();
	}
	private void createRegionString(StringBuffer fileString, ParamRegion region)  {
		//下面不能用‘{}’而用‘[]’组装数据，因为对象不按存储顺序输出导致后端地域列表排序失效，因此只能用数组
		List<ParamRegion> children= region.getChildren();
		if(children!= null && children.size()>0) {
			fileString.append(region.getCityCode());
			fileString.append(": [");
			for (int i = 0; i < children.size(); i++) {
				ParamRegion child = children.get(i);
				fileString.append("['");
				fileString.append(child.getCityCode());
				fileString.append("','");
				fileString.append(child.getName());
				if ((children.size() - 1) == i) {
					fileString.append("']");
				} else {
					fileString.append("'],");
				}
			}
			fileString.append("],");
			//组装子节点
			for (ParamRegion paramRegion : children) {
				createRegionString(fileString, paramRegion);
			}
		}
	}

	/**
	 * 导出列表
	 * @param queryEntity 查询条件
	 * @param cols 导出标题及其字段 格式：field1,title1;field2,title2;field3,title1
	 * @param exportType 导出类型 csv/xls
	 */
	@ResponseBody
	@RequestMapping(value = "/list/paramRegionList/toExport")
	public void toExport(ParamRegion queryEntity, String cols, String exportType, String downloadToken) throws Exception{
		Cookie cookie = new Cookie("downloadToken", downloadToken);
		cookie.setPath("/");
		cookie.setMaxAge(-1);
		response.reset();
		response.addCookie(cookie);

		//指定下载的文件名
		response.setContentType("multipart/form-data");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-Disposition", "attachment;filename=" + new String("列表导出".getBytes(),"iso-8859-1") + "."+("xls".equals(exportType)?"xlsx":"csv"));
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		QueryWrapper qw= new QueryWrapper(queryEntity);
		qw.orderByAsc("level,sort");
		List<ParamRegion> dataList= paramRegionService.listAll(new QueryWrapper(queryEntity));
		CommonExportUtil.createExcelWriter(response, cols, dataList);
		response.getOutputStream().flush();
	}
}
